// Copyright 2023 Huawei Cloud Computing Technology Co., Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import PROTOCOL_CONFIG from "./config/protocolConfig";
import Util from "./Util";

const KEYCODE_ENTER_NUMBER_ZONE = 108;
const KEYCODE_ENTER_CTRL_ZONE = 13;

export default class KeyboardInput {

    constructor(containerId, msgHandler) {
        this.containerId = containerId;
        this.msgHandler = msgHandler;
        this.util = new Util();
        this.inputContainer = null;
        this.input = null;
        this.inputId = 'keyboardInput' + Date.now();
    }

    init() {
        const videoContainer = document.getElementById(this.containerId);
        if (!videoContainer) {
            return;
        }

        this.inputContainer = document.createElement('div');
        this.inputContainer.id = 'keyboardInputContent';
        this.input = document.createElement('input');
        this.input.id = this.inputId;
        this.input.type = 'text';

        this.inputContainer.style.cssText = `
            display: none;
            position: absolute;
            bottom: 5px;
            left: 0px;
            height: 40px;
            width: 100%;
            `;
        this.input.style.cssText = `
            height: 40px;
            width: 100%;
            color: white;
            background-color: rgb(37,43,58);
            opacity: 0.8;
            box-sizing: border-box;
            `;
        this.util.bind(this.input, 'input', this.onInput.bind(this));
        this.util.bind(this.input, 'keyup', this.onKeyup.bind(this));
        this.inputContainer.appendChild(this.input);
        videoContainer.appendChild(this.inputContainer);
    }

    start(inputText) {
        this.input.valueOf = inputText;
        this.inputContainer.style.display = 'block';
        this.input.focus();
    }

    stop() {
        this.input.blur();
        this.inputContainer.style.display = 'none';
    }

    blurInput() {
        this.input.blur();
    }

    onInput() {
        this.handleInputMsg(this.input.value, 'KEYBOARD_INPUT');
    }

    onKeyup(event) {
        if (event.keyCode === KEYCODE_ENTER_NUMBER_ZONE || event.keyCode === KEYCODE_ENTER_CTRL_ZONE) {
            this.stop();
        }
    }

    handleInputMsg(input, msgType) {
        const PACKAGE_HEADER_LENGTH = 8;
        const INPUT_HEADER_LENGTH = 3;
        const msgData = this.util.encodeUTF8(input);
        const cmdBuf = new Uint8Array(PACKAGE_HEADER_LENGTH + INPUT_HEADER_LENGTH + msgData.length);
        cmdBuf[0] = 90;
        cmdBuf[1] = 90;
        cmdBuf[2] = 180 + PROTOCOL_CONFIG.MSG_TYPE[msgType];
        cmdBuf[3] = PROTOCOL_CONFIG.MSG_TYPE[msgType];
        cmdBuf[4] = (INPUT_HEADER_LENGTH + msgData.length) >> 24;
        cmdBuf[5] = (INPUT_HEADER_LENGTH + msgData.length) >> 16;
        cmdBuf[6] = (INPUT_HEADER_LENGTH + msgData.length) >> 8;
        cmdBuf[7] = (INPUT_HEADER_LENGTH + msgData.length);
        cmdBuf[8] = PROTOCOL_CONFIG.KEYBOARD_INPUT_MSG_TYPE.TEXT_UPDATE;
        cmdBuf[9] = msgData.length >> 8;
        cmdBuf[10] = msgData.length;

        cmdBuf.set(msgData, PACKAGE_HEADER_LENGTH + INPUT_HEADER_LENGTH);
        this.msgHandler(cmdBuf.buffer);
    }

    destroy() {
        this.util.unbind(this.input, 'input');
        this.util.unbind(this.input, 'keyup');
        this.inputContainer.remove();
        this.inputContainer = null;
    }
}